
package cn.ai.boot.config;

import java.time.Duration;
import java.time.LocalTime;

public class OvertimeCalculator2 {
    // 标准工作时间
    private static final LocalTime WORK_START = LocalTime.of(9, 0);
    private static final LocalTime WORK_END = LocalTime.of(18, 30);
    private static final LocalTime LUNCH_START = LocalTime.of(12, 0);
    private static final LocalTime LUNCH_END = LocalTime.of(13, 30);
    private static final Duration LUNCH_BREAK = Duration.between(LUNCH_START, LUNCH_END);
    private static final Duration TARGET_OVERTIME = Duration.ofHours(6); // 周一到周五目标加班时间
    private static final Duration SATURDAY_MIN_OVERTIME_4 = Duration.ofHours(4); // 周六最少加班4小时
    private static final Duration SATURDAY_MIN_OVERTIME_8 = Duration.ofHours(8); // 周六最少加班8小时

    // 周一到周五工作时间记录（上班时间，下班时间）
    private static final LocalTime[][] WEEK_SCHEDULE = {
            {LocalTime.of(8, 46), LocalTime.of(19, 48)},  // 周一
            {LocalTime.of(8, 52), LocalTime.of(18, 27)},   // 周二
            {LocalTime.of(8, 51), LocalTime.of(20, 55)},   // 周三
            {LocalTime.of(8, 53), LocalTime.of(20, 0)},  // 周四
            {LocalTime.of(8, 46), LocalTime.of(18, 30)}   // 周五
    };

    // 周六上班时间
    private static LocalTime SATURDAY_START = LocalTime.of(12, 0);

    public static void main(String[] args) {
        // 计算周一到周五总加班时间
        Duration totalWeekOvertime = Duration.ZERO;
        String[] weekDays = {"周一", "周二", "周三", "周四", "周五"};

        for (int i = 0; i < 5; i++) {
            Duration dailyOvertime = calculateDailyOvertime(WEEK_SCHEDULE[i]);
            System.out.printf("%s 加班时长: %s%n",
                    weekDays[i], formatDuration(dailyOvertime));
            totalWeekOvertime = totalWeekOvertime.plus(dailyOvertime);
        }

        System.out.println("周一到周五总加班: " + formatDuration(totalWeekOvertime));

        // 设置周六上班时间（可以根据需要修改）
//        SATURDAY_START = LocalTime.of(9, 46); // 这里可以修改为实际的周六上班时间

        // 计算周六需要的加班时间
        calculateSaturdayOvertime(totalWeekOvertime);
    }

    /**
     * 计算周六加班情况
     * @param weekOvertime 周一到周五加班总时长
     */
    private static void calculateSaturdayOvertime(Duration weekOvertime) {
        System.out.println("\n=== 周六加班计算 ===");
        System.out.println("周六上班时间: " + SATURDAY_START);
        System.out.println("午休时间: " + LUNCH_START + " - " + LUNCH_END + " (1.5小时不计入加班)");

        // 情况1: 周一到周五加班不足6小时，需要在周六补足
        Duration remainingTo6Hours = TARGET_OVERTIME.minus(weekOvertime);
        if (remainingTo6Hours.isNegative()) {
            System.out.printf("周一到周五已加班 %s，已超过6小时目标%n",
                    formatDuration(weekOvertime));
        } else {
            System.out.printf("周一到周五加班 %s，还需 %s 达到6小时目标%n",
                    formatDuration(weekOvertime), formatDuration(remainingTo6Hours));
        }

        // 计算6+4小时方案 (总共需要10小时加班)
        Duration totalTarget10 = TARGET_OVERTIME.plus(SATURDAY_MIN_OVERTIME_4);
        Duration saturdayNeeded4 = totalTarget10.minus(weekOvertime);

        if (saturdayNeeded4.isNegative()) {
            System.out.println("6+4方案：周六无需加班，已满足10小时总目标");
        } else {
            // 计算需要工作多长时间才能满足saturdayNeeded4的加班要求
            // 需要考虑午休时间，实际工作时间 = 需要的加班时间 + 午休时间
            Duration actualWorkTime = saturdayNeeded4.plus(LUNCH_BREAK);
            LocalTime saturdayEnd4 = SATURDAY_START.plus(actualWorkTime);
            System.out.printf("6+4方案：周六需有效加班 %s (+1.5小时午休)，最早下班时间 %s%n",
                    formatDuration(saturdayNeeded4), saturdayEnd4);
        }

        // 计算6+8小时方案 (总共需要14小时加班)
        Duration totalTarget14 = TARGET_OVERTIME.plus(SATURDAY_MIN_OVERTIME_8);
        Duration saturdayNeeded8 = totalTarget14.minus(weekOvertime);

        if (saturdayNeeded8.isNegative()) {
            System.out.println("6+8方案：周六无需加班，已满足14小时总目标");
        } else {
            // 计算需要工作多长时间才能满足saturdayNeeded8的加班要求
            Duration actualWorkTime = saturdayNeeded8.plus(LUNCH_BREAK);
            LocalTime saturdayEnd8 = SATURDAY_START.plus(actualWorkTime);
            System.out.printf("6+8方案：周六需有效加班 %s (+1.5小时午休)，最早下班时间 %s%n",
                    formatDuration(saturdayNeeded8), saturdayEnd8);
        }
    }

    private static Duration calculateDailyOvertime(LocalTime[] daySchedule) {
        Duration overtime = Duration.ZERO;

        // 计算早到时间
        Duration earlyArrival = Duration.between(daySchedule[0], WORK_START);
        if (!earlyArrival.isNegative()) {
            overtime = overtime.plus(earlyArrival);
        }

        // 计算加班时间
        Duration lateDeparture = Duration.between(WORK_END, daySchedule[1]);
        if (!lateDeparture.isNegative()) {
            overtime = overtime.plus(lateDeparture);
        }

        return overtime;
    }

    private static String formatDuration(Duration duration) {
        long hours = duration.toHours();
        long minutes = duration.minusHours(hours).toMinutes();
        return String.format("%d小时%d分钟", hours, minutes);
    }

    // 提供设置周六上班时间的方法
    public static void setSaturdayStart(LocalTime saturdayStart) {
        SATURDAY_START = saturdayStart;
    }

    // 提供获取周六上班时间的方法
    public static LocalTime getSaturdayStart() {
        return SATURDAY_START;
    }
}